static int sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); struct sna_present_event *event; union drm_wait_vblank vbl; DBG(("%s(pipe=%d, event=%lld, msc=%lld)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, (long long)msc)); event = malloc(sizeof(struct sna_present_event)); if (event == NULL) return BadAlloc; event->event_id = event_id; event->crtc = crtc->devPrivate; VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(event); if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(event->crtc))) { DBG(("%s: vblank enqueue failed\n", __FUNCTION__)); free(event); return BadMatch; } return Success; }
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); }
static int pipe_from_crtc(RRCrtcPtr crtc) { return crtc ? sna_crtc_to_pipe(crtc->devPrivate) : -1; }