uterm: video: add display callbacks

Users might be interested in vertical-blank events so we now allow them to
register event-callbacks on displays. The only event that we currently
pass is a page-flip event that is always sent as reaction to a swap. If
there is no hardware support for such events, we simply throw it from
within the swap() function.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-10-15 12:26:03 +02:00
parent 6636bc6ca3
commit efd00b154e
6 changed files with 60 additions and 4 deletions

View File

@ -127,6 +127,14 @@ struct uterm_video_hotplug {
int action;
};
enum uterm_display_action {
UTERM_PAGE_FLIP,
};
struct uterm_display_event {
int action;
};
enum uterm_video_format {
UTERM_FORMAT_GREY,
UTERM_FORMAT_XRGB32,
@ -155,6 +163,9 @@ struct uterm_video_blend_req {
typedef void (*uterm_video_cb) (struct uterm_video *video,
struct uterm_video_hotplug *arg,
void *data);
typedef void (*uterm_display_cb) (struct uterm_display *disp,
struct uterm_display_event *arg,
void *data);
/* misc */
@ -203,6 +214,11 @@ void uterm_display_ref(struct uterm_display *disp);
void uterm_display_unref(struct uterm_display *disp);
struct uterm_display *uterm_display_next(struct uterm_display *disp);
int uterm_display_register_cb(struct uterm_display *disp, uterm_display_cb cb,
void *data);
void uterm_display_unregister_cb(struct uterm_display *disp,
uterm_display_cb cb, void *data);
struct uterm_mode *uterm_display_get_modes(struct uterm_display *disp);
struct uterm_mode *uterm_display_get_current(struct uterm_display *disp);
struct uterm_mode *uterm_display_get_default(struct uterm_display *disp);

View File

@ -270,14 +270,20 @@ int display_new(struct uterm_display **out, const struct display_ops *ops)
disp->ref = 1;
disp->ops = ops;
ret = VIDEO_CALL(disp->ops->init, 0, disp);
ret = shl_hook_new(&disp->hook);
if (ret)
goto err_free;
ret = VIDEO_CALL(disp->ops->init, 0, disp);
if (ret)
goto err_hook;
log_info("new display %p", disp);
*out = disp;
return 0;
err_hook:
shl_hook_free(disp->hook);
err_free:
free(disp);
return ret;
@ -307,6 +313,7 @@ void uterm_display_unref(struct uterm_display *disp)
mode->next = NULL;
uterm_mode_unref(mode);
}
shl_hook_free(disp->hook);
free(disp);
}
@ -318,6 +325,24 @@ struct uterm_display *uterm_display_next(struct uterm_display *disp)
return disp->next;
}
int uterm_display_register_cb(struct uterm_display *disp, uterm_display_cb cb,
void *data)
{
if (!disp)
return -EINVAL;
return shl_hook_add_cast(disp->hook, cb, data);
}
void uterm_display_unregister_cb(struct uterm_display *disp,
uterm_display_cb cb, void *data)
{
if (!disp)
return;
shl_hook_rm_cast(disp->hook, cb, data);
}
struct uterm_mode *uterm_display_get_modes(struct uterm_display *disp)
{
if (!disp)

View File

@ -337,6 +337,7 @@ struct uterm_display {
struct uterm_display *next;
struct uterm_video *video;
struct shl_hook *hook;
struct uterm_mode *modes;
struct uterm_mode *default_mode;
struct uterm_mode *current_mode;
@ -352,6 +353,11 @@ struct uterm_display {
int display_new(struct uterm_display **out, const struct display_ops *ops);
#define DISPLAY_CB(disp, act) shl_hook_call((disp)->hook, (disp), \
&(struct uterm_display_event){ \
.action = (act), \
})
static inline bool display_is_conn(const struct uterm_display *disp)
{
return disp->video;

View File

@ -979,8 +979,11 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
{
struct uterm_display *disp = data;
disp->flags &= ~DISPLAY_VSYNC;
uterm_display_unref(disp);
if (disp->flags & DISPLAY_VSYNC) {
disp->flags &= ~DISPLAY_VSYNC;
DISPLAY_CB(disp, UTERM_PAGE_FLIP);
}
}
static void event(struct ev_fd *fd, int mask, void *data)

View File

@ -742,8 +742,11 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
{
struct uterm_display *disp = data;
disp->flags &= ~DISPLAY_VSYNC;
uterm_display_unref(disp);
if (disp->flags & DISPLAY_VSYNC) {
disp->flags &= ~DISPLAY_VSYNC;
DISPLAY_CB(disp, UTERM_PAGE_FLIP);
}
}
static void event(struct ev_fd *fd, int mask, void *data)

View File

@ -343,8 +343,10 @@ static int display_swap(struct uterm_display *disp)
if (!(disp->flags & DISPLAY_ONLINE))
return -EINVAL;
if (!(disp->flags & DISPLAY_DBUF))
if (!(disp->flags & DISPLAY_DBUF)) {
DISPLAY_CB(disp, UTERM_PAGE_FLIP);
return 0;
}
vinfo = &disp->fbdev.vinfo;
vinfo->activate = FB_ACTIVATE_VBL;
@ -362,6 +364,7 @@ static int display_swap(struct uterm_display *disp)
}
disp->fbdev.bufid ^= 1;
DISPLAY_CB(disp, UTERM_PAGE_FLIP);
return 0;
}