static int sna_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); int pipe = pipe_from_crtc(crtc); union drm_wait_vblank vbl; DBG(("%s(pipe=%d)\n", __FUNCTION__, pipe)); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; if (sna_wait_vblank(sna, &vbl, pipe) == 0) { *ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); *msc = sna_crtc_record_vblank(crtc->devPrivate, &vbl); } else { const struct ust_msc *swap = sna_crtc_last_swap(crtc->devPrivate); *ust = ust64(swap->tv_sec, swap->tv_usec); *msc = swap->msc; } DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__, pipe, (int)(*ust / 1000000), (int)(*ust % 1000000), (long long)*msc)); return Success; }
static void sna_present_unflip(ScreenPtr screen, uint64_t event_id) { struct sna *sna = to_sna_from_screen(screen); struct kgem_bo *bo; DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id)); if (sna->mode.front_active == 0 || sna->mode.shadow_active) { const struct ust_msc *swap; DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__)); notify: swap = sna_crtc_last_swap(sna_mode_first_crtc(sna)); DBG(("%s: pipe=%d, tv=%d.%06d msc %lld, event %lld complete\n", __FUNCTION__, -1, swap->tv_sec, swap->tv_usec, (long long)swap->msc, (long long)event_id)); present_event_notify(event_id, ust64(swap->tv_sec, swap->tv_usec), swap->msc); return; } bo = get_flip_bo(screen->GetScreenPixmap(screen)); if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) { DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__)); xf86SetDesiredModes(sna->scrn); goto notify; } }
static uint64_t gettime_ust64(void) { struct timespec tv; if (clock_gettime(CLOCK_MONOTONIC, &tv)) return 0; return ust64(tv.tv_sec, tv.tv_nsec / 1000); }
void sna_present_vblank_handler(struct sna *sna, struct drm_event_vblank *event) { struct sna_present_event *info = to_present_event(event->user_data); DBG(("%s: pipe=%d event=%lld, tv=%d.%06d msc=%d\n", __FUNCTION__, sna_crtc_to_pipe(info->crtc), (long long)info->event_id, event->tv_sec, event->tv_usec, event->sequence)); present_event_notify(info->event_id, ust64(event->tv_sec, event->tv_usec), sna_crtc_record_event(info->crtc, event)); free(info); }
static void present_flip_handler(struct drm_event_vblank *event, void *data) { struct sna_present_event *info = data; struct ust_msc swap; DBG(("%s(sequence=%d)\n", __FUNCTION__, event->sequence)); if (info->crtc == NULL) { swap.tv_sec = event->tv_sec; swap.tv_usec = event->tv_usec; swap.msc = event->sequence; } else swap = *sna_crtc_last_swap(info->crtc); DBG(("%s: pipe=%d, tv=%d.%06d msc %lld, event %lld complete\n", __FUNCTION__, info->crtc ? sna_crtc_to_pipe(info->crtc) : -1, swap.tv_sec, swap.tv_usec, (long long)swap.msc, (long long)info->event_id)); present_event_notify(info->event_id, ust64(swap.tv_sec, swap.tv_usec), swap.msc); free(info); }