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:
parent
6636bc6ca3
commit
efd00b154e
16
src/uterm.h
16
src/uterm.h
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user