summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;