static void nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data) { struct nouveau_dri2_vblank_state *flip = event_data; DrawablePtr draw; ScreenPtr screen; ScrnInfoPtr scrn; int status; status = dixLookupDrawable(&draw, flip->draw, serverClient, M_ANY, DixWriteAccess); if (status != Success) { free(flip); return; } screen = draw->pScreen; scrn = xf86ScreenToScrn(screen); /* We assume our flips arrive in order, so we don't check the frame */ switch (flip->action) { case SWAP: /* Check for too small vblank count of pageflip completion, * taking wraparound into account. This usually means some * defective kms pageflip completion, causing wrong (msc, ust) * return values and possible visual corruption. * Skip test for frame == 0, as this is a valid constant value * reported by all Linux kernels at least up to Linux 3.0. */ if ((frame != 0) && (frame < flip->frame) && (flip->frame - frame < 5)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: Pageflip has impossible msc %d < target_msc %d\n", __func__, frame, flip->frame); /* All-Zero values signal failure of (msc, ust) * timestamping to client. */ frame = tv_sec = tv_usec = 0; } DRI2SwapComplete(flip->client, draw, frame, tv_sec, tv_usec, DRI2_FLIP_COMPLETE, flip->func, flip->data); break; default: xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); /* Unknown type */ break; } free(flip); }
static void vivante_dri2_blit(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back, unsigned frame, unsigned tv_sec, unsigned tv_usec, DRI2SwapEventPtr func, void *data) { RegionRec region; BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = draw->width; box.y2 = draw->height; RegionInit(®ion, &box, 0); vivante_dri2_CopyRegion(draw, ®ion, front, back); DRI2SwapComplete(client, draw, frame, tv_sec, tv_usec, DRI2_BLIT_COMPLETE, func, data); }
static void nouveau_dri2_vblank_handler(void *priv, uint64_t name, uint64_t ust, uint32_t frame) { struct dri2_vblank *event = priv; struct nouveau_dri2_vblank_state *s = event->s; uint32_t tv_sec = ust / 1000000; uint32_t tv_usec = ust % 1000000; DrawablePtr draw; int ret; ret = dixLookupDrawable(&draw, s->draw, serverClient, M_ANY, DixWriteAccess); if (ret) { free(s); return; } switch (s->action) { case SWAP: nouveau_dri2_finish_swap(draw, frame, tv_sec, tv_usec, s); #if DRI2INFOREC_VERSION >= 6 /* Restore real swap limit on drawable, now that it is safe. */ ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); DRI2SwapLimit(draw, NVPTR(scrn)->swap_limit); #endif break; case WAIT: DRI2WaitMSCComplete(s->client, draw, frame, tv_sec, tv_usec); free(s); break; case BLIT: DRI2SwapComplete(s->client, draw, frame, tv_sec, tv_usec, DRI2_BLIT_COMPLETE, s->func, s->data); free(s); break; } }