summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2015-10-26 11:35:38 +0000
committerRussell King <rmk@arm.linux.org.uk>2015-10-26 19:38:57 +0000
commitef389167b5a505b75bf89aa85bd57bc651f0aa74 (patch)
tree6d0d1845329453b9a21054cc448c0cf3eabdd77d
parentdacc4267b6a391b053aeb48d7a111ac2eb1056e8 (diff)
src: introduce common DRM event handling
Introduce a base drm event structure for all DRM events, which allows us to abstract the event handling between each of the different events, and localise the DRI2 event handling entirely within common_drm_dri2.c Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--etnaviv/etnaviv_dri2.c8
-rw-r--r--src/armada_drm.c6
-rw-r--r--src/common_drm.c94
-rw-r--r--src/common_drm.h16
-rw-r--r--src/common_drm_dri2.c52
-rw-r--r--src/common_drm_dri2.h12
-rw-r--r--src/common_drm_helper.h3
-rw-r--r--vivante/vivante_dri2.c8
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;