diff options
-rw-r--r-- | etnaviv/etnaviv_dri2.c | 8 | ||||
-rw-r--r-- | src/armada_drm.c | 6 | ||||
-rw-r--r-- | src/common_drm.c | 94 | ||||
-rw-r--r-- | src/common_drm.h | 16 | ||||
-rw-r--r-- | src/common_drm_dri2.c | 52 | ||||
-rw-r--r-- | src/common_drm_dri2.h | 12 | ||||
-rw-r--r-- | src/common_drm_helper.h | 3 | ||||
-rw-r--r-- | vivante/vivante_dri2.c | 8 |
8 files changed, 103 insertions, 96 deletions
diff --git a/etnaviv/etnaviv_dri2.c b/etnaviv/etnaviv_dri2.c index f537b0c..97bfc34 100644 --- a/etnaviv/etnaviv_dri2.c +++ b/etnaviv/etnaviv_dri2.c @@ -168,7 +168,7 @@ static Bool etnaviv_dri2_ScheduleFlip(DrawablePtr drawable, assert(front == to_common_dri2_buffer(wait->front)->pixmap); - if (common_drm_flip(pScrn, back, wait, wait->crtc)) { + if (common_drm_flip(pScrn, back, &wait->base, wait->base.crtc)) { struct etnaviv_pixmap *f_pix = etnaviv_get_pixmap_priv(front); struct etnaviv_pixmap *b_pix = etnaviv_get_pixmap_priv(back); @@ -216,12 +216,11 @@ static int etnaviv_dri2_ScheduleSwap(ClientPtr client, DrawablePtr draw, divisor &= 0xffffffff; remainder &= 0xffffffff; - wait = common_dri2_wait_alloc(client, draw, DRI2_SWAP); + wait = common_dri2_wait_alloc(client, draw, crtc, DRI2_SWAP); if (!wait) goto blit; wait->event_func = etnaviv_dri2_swap; - wait->crtc = crtc; wait->swap_func = func; wait->swap_data = data; wait->front = front; @@ -294,7 +293,8 @@ static int etnaviv_dri2_ScheduleSwap(ClientPtr client, DrawablePtr draw, } ret = common_drm_vblank_queue_event(pScrn, crtc, &vbl, __FUNCTION__, - wait->type != DRI2_FLIP, wait); + wait->type != DRI2_FLIP, + &wait->base); if (ret) goto blit_free; diff --git a/src/armada_drm.c b/src/armada_drm.c index c3084ac..585e285 100644 --- a/src/armada_drm.c +++ b/src/armada_drm.c @@ -18,7 +18,6 @@ #include "armada_accel.h" #include "armada_drm.h" #include "common_drm.h" -#include "common_drm_dri2.h" #include "xf86_OSproc.h" #include "xf86Crtc.h" #include "xf86cmap.h" @@ -603,11 +602,6 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn) drm->common.cursor_max_width = CURSOR_MAX_WIDTH; drm->common.cursor_max_height = CURSOR_MAX_HEIGHT; drm->common.private = &drm->armada; - drm->common.event_context.version = DRM_EVENT_CONTEXT_VERSION; -#ifdef HAVE_DRI2 - drm->common.event_context.vblank_handler = common_dri2_event; - drm->common.event_context.page_flip_handler = common_drm_flip_handler; -#endif for (i = 0; i < ARRAY_SIZE(drm_module_names); i++) { drm->common.fd = drmOpen(drm_module_names[i], busid); diff --git a/src/common_drm.c b/src/common_drm.c index 0e4042b..db71134 100644 --- a/src/common_drm.c +++ b/src/common_drm.c @@ -19,7 +19,6 @@ #include "boxutil.h" #include "common_drm.h" -#include "common_drm_dri2.h" #include "common_drm_helper.h" #include "xf86_OSproc.h" #include "xf86Crtc.h" @@ -723,6 +722,14 @@ static Bool common_drm_crtc_init(ScrnInfoPtr pScrn, unsigned num, return TRUE; } +static void common_drm_event(int fd, unsigned int frame, unsigned int tv_sec, + unsigned int tv_usec, void *event_data) +{ + struct common_drm_event *event = event_data; + + event->handler(event, frame, tv_sec, tv_usec); +} + Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn, const xf86CrtcFuncsRec *funcs) { @@ -730,6 +737,10 @@ Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn, Gamma zeros = { 0.0, 0.0, 0.0 }; int i; + drm->event_context.version = DRM_EVENT_CONTEXT_VERSION; + drm->event_context.vblank_handler = common_drm_event; + drm->event_context.page_flip_handler = common_drm_event; + drm->mode_res = drmModeGetResources(drm->fd); if (!drm->mode_res) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -771,14 +782,34 @@ Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn, return TRUE; } -struct common_crtc_flip { - struct common_drm_info *drm; - Bool ref; -}; +static void common_drm_flip_handler(struct common_drm_event *event, + unsigned int frame, unsigned int tv_sec, unsigned int tv_usec) +{ + struct common_drm_info *drm = event->drm; + + if (drm->flip_ref_crtc == event->crtc) { + drm->flip_frame = frame; + drm->flip_tv_sec = tv_sec; + drm->flip_tv_usec = tv_usec; + } + + free(event); + + if (--drm->flip_count) + return; + + drmModeRmFB(drm->fd, drm->flip_old_fb_id); + + /* Now pass the event on to the flip complete event handler */ + event = drm->flip_event; + if (event) + event->handler(event, drm->flip_frame, drm->flip_tv_sec, + drm->flip_tv_usec); +} _X_EXPORT Bool common_drm_flip(ScrnInfoPtr pScrn, PixmapPtr pixmap, - struct common_dri2_wait *flip_info, xf86CrtcPtr ref_crtc) + struct common_drm_event *event, xf86CrtcPtr ref_crtc) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); struct common_drm_info *drm = GET_DRM_INFO(pScrn); @@ -801,35 +832,37 @@ Bool common_drm_flip(ScrnInfoPtr pScrn, PixmapPtr pixmap, for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; struct common_crtc_info *drmc; - struct common_crtc_flip *flip; + struct common_drm_event *event; if (!crtc->enabled) continue; - flip = calloc(1, sizeof *flip); - if (!flip) { + event = calloc(1, sizeof *event); + if (!event) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "page flip: malloc failed\n"); continue; } - flip->drm = drm; - flip->ref = ref_crtc == crtc; + event->crtc = crtc; + event->drm = drm; + event->handler = common_drm_flip_handler; drmc = common_crtc(crtc); if (drmModePageFlip(drm->fd, drmc->mode_crtc->crtc_id, drm->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - flip)) { + event)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "page flip: queue failed: %s\n", strerror(errno)); - free(flip); + free(event); continue; } drm->flip_count++; } if (drm->flip_count) { - drm->flip_info = flip_info; + drm->flip_event = event; + drm->flip_ref_crtc = ref_crtc; drm->flip_frame = 0; drm->flip_tv_sec = 0; drm->flip_tv_usec = 0; @@ -843,34 +876,6 @@ Bool common_drm_flip(ScrnInfoPtr pScrn, PixmapPtr pixmap, return FALSE; } -void common_drm_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - struct common_crtc_flip *flip = event_data; - struct common_drm_info *drm = flip->drm; - - if (flip->ref) { - drm->flip_frame = frame; - drm->flip_tv_sec = tv_sec; - drm->flip_tv_usec = tv_usec; - } - - free(flip); - - if (--drm->flip_count) - return; - - drmModeRmFB(drm->fd, drm->flip_old_fb_id); - -#ifdef HAVE_DRI2 - if (drm->flip_info) { - common_dri2_event(fd, drm->flip_frame, drm->flip_tv_sec, - drm->flip_tv_usec, drm->flip_info); - drm->flip_info = NULL; - } -#endif -} - void common_drm_flip_pixmap(ScreenPtr pScreen, PixmapPtr front, PixmapPtr b) { struct common_pixmap front_c; @@ -1391,14 +1396,15 @@ int common_drm_get_msc(xf86CrtcPtr crtc, uint64_t *ust, uint64_t *msc) _X_EXPORT int common_drm_vblank_queue_event(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, - drmVBlank *vbl, const char *func, Bool nextonmiss, void *signal) + drmVBlank *vbl, const char *func, Bool nextonmiss, + struct common_drm_event *event) { struct common_drm_info *drm = GET_DRM_INFO(pScrn); int ret; vbl->request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | req_crtc(crtc); - vbl->request.signal = (unsigned long)signal; + vbl->request.signal = (unsigned long)event; if (nextonmiss) vbl->request.type |= DRM_VBLANK_NEXTONMISS; diff --git a/src/common_drm.h b/src/common_drm.h index fc3eb48..647ed1b 100644 --- a/src/common_drm.h +++ b/src/common_drm.h @@ -5,7 +5,7 @@ #include "xf86drmMode.h" #include "compat-api.h" -struct common_dri2_wait; +struct common_drm_event; struct common_crtc_info { int drm_fd; @@ -31,7 +31,8 @@ struct common_drm_info { drmModeResPtr mode_res; drmEventContext event_context; - struct common_dri2_wait *flip_info; + struct common_drm_event *flip_event; + xf86CrtcPtr flip_ref_crtc; unsigned int flip_count; unsigned int flip_frame; unsigned int flip_tv_sec; @@ -55,6 +56,13 @@ struct common_drm_info { void *private; }; +struct common_drm_event { + struct common_drm_info *drm; + xf86CrtcPtr crtc; + void (*handler)(struct common_drm_event *, unsigned int frame, + unsigned int tv_sec, unsigned int tv_usec); +}; + extern const OptionInfoRec common_drm_options[]; #define GET_DRM_INFO(pScrn) ((struct common_drm_info *)(pScrn)->driverPrivate) @@ -81,9 +89,7 @@ Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn, const xf86CrtcFuncsRec *funcs); Bool common_drm_flip(ScrnInfoPtr pScrn, PixmapPtr pixmap, - struct common_dri2_wait *flip_info, xf86CrtcPtr ref_crtc); -void common_drm_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data); + struct common_drm_event *event, xf86CrtcPtr ref_crtc); void common_drm_flip_pixmap(ScreenPtr pScreen, PixmapPtr a, PixmapPtr b); void common_drm_LoadPalette(ScrnInfoPtr pScrn, int num, int *indices, diff --git a/src/common_drm_dri2.c b/src/common_drm_dri2.c index 92332b9..95f44f5 100644 --- a/src/common_drm_dri2.c +++ b/src/common_drm_dri2.c @@ -64,9 +64,31 @@ static Bool common_dri2_add_reslist(XID id, RESTYPE type, return TRUE; } +static void common_dri2_event(struct common_drm_event *event, unsigned frame, + unsigned tv_sec, unsigned tv_usec) +{ + struct common_dri2_wait *wait = container_of(event, struct common_dri2_wait, base); + DrawablePtr draw; + + if (wait->drawable_id && + dixLookupDrawable(&draw, wait->drawable_id, serverClient, M_ANY, + DixWriteAccess) == Success) { + if (wait->event_func) { + wait->event_func(wait, draw, frame, tv_sec, tv_usec); + return; + } + + xf86DrvMsg(xf86ScreenToScrn(draw->pScreen)->scrnIndex, + X_WARNING, "%s: unknown vblank event received\n", + __FUNCTION__); + } + common_dri2_wait_free(wait); +} + _X_EXPORT struct common_dri2_wait *__common_dri2_wait_alloc(ClientPtr client, - DrawablePtr draw, enum common_dri2_event_type type, size_t size) + DrawablePtr draw, xf86CrtcPtr crtc, enum common_dri2_event_type type, + size_t size) { struct common_dri2_wait *wait; @@ -75,6 +97,8 @@ struct common_dri2_wait *__common_dri2_wait_alloc(ClientPtr client, wait = calloc(1, size); if (wait) { + wait->base.crtc = crtc; + wait->base.handler = common_dri2_event; wait->drawable_id = draw->id; wait->client = client; wait->type = type; @@ -288,7 +312,7 @@ Bool common_dri2_ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, if (!crtc) goto complete; - wait = common_dri2_wait_alloc(client, draw, DRI2_WAITMSC); + wait = common_dri2_wait_alloc(client, draw, crtc, DRI2_WAITMSC); if (!wait) goto complete; @@ -329,7 +353,7 @@ Bool common_dri2_ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, } ret = common_drm_vblank_queue_event(pScrn, crtc, &vbl, __FUNCTION__, - FALSE, wait); + FALSE, &wait->base); if (ret) goto del_wait; @@ -346,28 +370,6 @@ Bool common_dri2_ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, return TRUE; } -_X_EXPORT -void common_dri2_event(int fd, unsigned frame, unsigned tv_sec, - unsigned tv_usec, void *event) -{ - struct common_dri2_wait *wait = event; - DrawablePtr draw; - - if (wait->drawable_id && - dixLookupDrawable(&draw, wait->drawable_id, serverClient, M_ANY, - DixWriteAccess) == Success) { - if (wait->event_func) { - wait->event_func(wait, draw, frame, tv_sec, tv_usec); - return; - } - - xf86DrvMsg(xf86ScreenToScrn(draw->pScreen)->scrnIndex, - X_WARNING, "%s: unknown vblank event received\n", - __FUNCTION__); - } - common_dri2_wait_free(wait); -} - static int common_dri2_client_gone(void *data, XID id) { struct xorg_list *list = data; diff --git a/src/common_drm_dri2.h b/src/common_drm_dri2.h index 3db84e0..2495269 100644 --- a/src/common_drm_dri2.h +++ b/src/common_drm_dri2.h @@ -25,6 +25,7 @@ enum common_dri2_event_type { }; struct common_dri2_wait { + struct common_drm_event base; struct xorg_list drawable_list; struct xorg_list client_list; XID drawable_id; @@ -34,7 +35,6 @@ struct common_dri2_wait { void (*event_func)(struct common_dri2_wait *wait, DrawablePtr draw, unsigned frame, unsigned tv_sec, unsigned tv_usec); enum common_dri2_event_type type; - xf86CrtcPtr crtc; int frame; /* For swaps/flips */ @@ -60,12 +60,13 @@ static inline DrawablePtr common_dri2_get_drawable(DRI2BufferPtr buffer, struct common_dri2_wait *__common_dri2_wait_alloc(ClientPtr client, - DrawablePtr draw, enum common_dri2_event_type type, size_t size); + DrawablePtr draw, xf86CrtcPtr crtc, enum common_dri2_event_type type, + size_t size); static inline struct common_dri2_wait *common_dri2_wait_alloc(ClientPtr client, - DrawablePtr draw, enum common_dri2_event_type type) + DrawablePtr draw, xf86CrtcPtr crtc, enum common_dri2_event_type type) { - return __common_dri2_wait_alloc(client, draw, type, + return __common_dri2_wait_alloc(client, draw, crtc, type, sizeof(struct common_dri2_wait)); } @@ -87,9 +88,6 @@ int common_dri2_GetMSC(DrawablePtr draw, CARD64 *ust, CARD64 *msc); Bool common_dri2_ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc, CARD64 divisor, CARD64 remainder); -void common_dri2_event(int fd, unsigned frame, unsigned tv_sec, - unsigned tv_usec, void *event); - Bool common_dri2_ScreenInit(ScreenPtr pScreen); #endif diff --git a/src/common_drm_helper.h b/src/common_drm_helper.h index 5795d9e..7b59033 100644 --- a/src/common_drm_helper.h +++ b/src/common_drm_helper.h @@ -16,7 +16,8 @@ int common_drm_vblank_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, int common_drm_get_msc(xf86CrtcPtr crtc, uint64_t *ust, uint64_t *msc); int common_drm_vblank_queue_event(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, - drmVBlank *vbl, const char *func, Bool nextonmiss, void *signal); + drmVBlank *vbl, const char *func, Bool nextonmiss, + struct common_drm_event *event); int common_drm_vblank_wait(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, drmVBlank *vbl, const char *func, Bool nextonmiss); diff --git a/vivante/vivante_dri2.c b/vivante/vivante_dri2.c index 661e183..c5429ae 100644 --- a/vivante/vivante_dri2.c +++ b/vivante/vivante_dri2.c @@ -142,7 +142,7 @@ static Bool vivante_dri2_ScheduleFlip(DrawablePtr drawable, assert(front == to_common_dri2_buffer(wait->front)->pixmap); - if (common_drm_flip(pScrn, back, wait, wait->crtc)) { + if (common_drm_flip(pScrn, back, &wait->base, wait->base.crtc)) { struct vivante_pixmap *f_pix = vivante_get_pixmap_priv(front); struct vivante_pixmap *b_pix = vivante_get_pixmap_priv(back); @@ -221,12 +221,11 @@ vivante_dri2_ScheduleSwap(ClientPtr client, DrawablePtr draw, divisor &= 0xffffffff; remainder &= 0xffffffff; - wait = common_dri2_wait_alloc(client, draw, DRI2_SWAP); + wait = common_dri2_wait_alloc(client, draw, crtc, DRI2_SWAP); if (!wait) goto blit; wait->event_func = vivante_dri2_swap; - wait->crtc = crtc; wait->swap_func = func; wait->swap_data = data; wait->front = front; @@ -299,7 +298,8 @@ vivante_dri2_ScheduleSwap(ClientPtr client, DrawablePtr draw, } ret = common_drm_vblank_queue_event(pScrn, crtc, &vbl, __FUNCTION__, - wait->type != DRI2_FLIP, wait); + wait->type != DRI2_FLIP, + &wait->base); if (ret) goto blit_free; |